# AI项目结构可视化工具.ps1
# 用于展示项目文件结构和内容，方便AI理解和复制

# 导入必要的程序集
Add-Type -AssemblyName System.Windows.Forms

# 创建文件夹选择对话框
function Select-FolderDialog {
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $folderBrowser.Description = "选择要展示的项目文件夹"
    $folderBrowser.ShowNewFolderButton = $false
    
    if ($folderBrowser.ShowDialog() -eq "OK") {
        return $folderBrowser.SelectedPath
    }
    return $null
}

# 判断文件是否为文本文件
function Test-TextFile {
    param($FilePath)
    
    # 常见的文本文件扩展名
    $textExtensions = @(
        '.txt', '.md', '.ps1', '.bat', '.cmd', '.sh',
        '.html', '.htm', '.css', '.js', '.json', '.xml', 
        '.yaml', '.yml', '.toml', '.ini', '.config',
        '.py', '.java', '.c', '.cpp', '.h', '.cs', 
        '.php', '.rb', '.go', '.rs', '.swift', '.kt',
        '.vue', '.jsx', '.tsx', '.scss', '.sass', '.less',
        '.sql', '.env', '.gitignore', '.dockerfile', '.makefile'
    )
    
    $extension = [System.IO.Path]::GetExtension($FilePath).ToLower()
    
    # 没有扩展名的文件（如Dockerfile, Makefile等）也尝试读取
    if ([string]::IsNullOrEmpty($extension)) {
        return $true
    }
    
    return $textExtensions -contains $extension
}

# 获取文件内容
function Get-FileContentSafe {
    param($FilePath)
    
    try {
        # 尝试以UTF8编码读取
        $content = Get-Content -Path $FilePath -Encoding UTF8 -ErrorAction Stop
        return $content -join "`n"
    }
    catch {
        try {
            # 如果UTF8失败，尝试系统默认编码
            $content = Get-Content -Path $FilePath -Encoding Default -ErrorAction Stop
            return $content -join "`n"
        }
        catch {
            return "[无法读取文件内容: $_]"
        }
    }
}

# 主函数
function Export-ProjectStructure {
    # 选择文件夹
    $selectedFolder = Select-FolderDialog
    
    if (-not $selectedFolder) {
        Write-Host "未选择文件夹，操作已取消" -ForegroundColor Yellow
        return
    }
    
    Write-Host "`n正在分析文件夹: $selectedFolder" -ForegroundColor Green
    Write-Host ("=" * 80) -ForegroundColor Gray
    
    # 获取所有文件（递归）
    $files = Get-ChildItem -Path $selectedFolder -File -Recurse -ErrorAction SilentlyContinue
    
    # 输出结果
    $output = @()
    $processedCount = 0
    $skippedCount = 0
    
    foreach ($file in $files) {
        # 获取相对路径
        $relativePath = $file.FullName.Substring($selectedFolder.Length + 1)
        $relativePath = "./" + $relativePath.Replace('\', '/')
        
        # 检查是否为文本文件
        if (Test-TextFile -FilePath $file.FullName) {
            $processedCount++
            
            # 添加文件路径
            $output += $relativePath
            
            # 添加文件内容
            $content = Get-FileContentSafe -FilePath $file.FullName
            $output += $content
            $output += ""  # 添加空行分隔
            
            # 显示进度
            Write-Host "处理: $relativePath" -ForegroundColor Cyan
        }
        else {
            $skippedCount++
            Write-Host "跳过二进制文件: $relativePath" -ForegroundColor DarkGray
        }
    }
    
    # 统计信息
    Write-Host "`n" ("=" * 80) -ForegroundColor Gray
    Write-Host "处理完成！" -ForegroundColor Green
    Write-Host "已处理文件: $processedCount 个" -ForegroundColor Yellow
    Write-Host "跳过文件: $skippedCount 个" -ForegroundColor Yellow
    
    # 输出结果到剪贴板和文件
    if ($output.Count -gt 0) {
        $outputText = $output -join "`n"
        
        # 复制到剪贴板
        $outputText | Set-Clipboard
        Write-Host "`n结果已复制到剪贴板！" -ForegroundColor Green
        
        # 保存到文件
        $outputFile = Join-Path -Path $selectedFolder -ChildPath "AI_项目结构_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
        $outputText | Out-File -FilePath $outputFile -Encoding UTF8
        Write-Host "结果已保存到: $outputFile" -ForegroundColor Green
        
        # 询问是否在控制台显示
        $showInConsole = Read-Host "`n是否在控制台显示完整内容？(y/n)"
        if ($showInConsole -eq 'y') {
            Write-Host "`n完整内容：" -ForegroundColor Magenta
            Write-Host ("=" * 80) -ForegroundColor Gray
            Write-Host $outputText
        }
    }
    else {
        Write-Host "未找到可处理的文件" -ForegroundColor Red
    }
}

# 运行主函数
Export-ProjectStructure

# 等待用户按键退出
Write-Host "`n按任意键退出..." -ForegroundColor Gray
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")